'use strict';

angular.module('app.view-en.fan-data-problem')
    .config(['$stateProvider', function($stateProvider) {
        $stateProvider.state('en-inaccurate-SD', {
            url: '/views-en/fan-data-problem/inaccurate-SD',
            views: {
                'navigation': {
                    templateUrl: 'views-en/header/navigation.html',
                    controller: 'en-navigationCtrl'
                },
                'sidebar': {
                    templateUrl: 'views-en/sidebar/sidebar-fan-data-problem.html',
                    controller: 'en-sidebarCtrl'
                },
                'content': {
                    templateUrl: 'views-en/fan-data-problem/inaccurate/inaccurate-SD.html',
                    controller: 'en-inaccurateSDCtrl'
                }
            }
        })
    }])

    .controller('en-inaccurateSDCtrl', ['$scope', 'Upload', 'communicationService', '$window',

        function($scope, Upload, communicationService, $window) {


            $scope.backToDetection = function()
            {
                $scope.detectionProcess = true;
                $scope.detection();
            };

            $scope.detectionProcess = true;
            $scope.canNotGoToRepair = true;
            
            $scope.outputDetectionPath = "detection_result.csv";
            $scope.outputRepairPath = "repair_result.csv";
            $scope.detectionLeftBound = 0.0;
            $scope.detectionRightBound = 0.1;
            $scope.detectionConfidence = 0.9;
            $scope.detectionSupport = 5;

            $scope.repairAlgorithmAttr = 10;

            $scope.autoCompleteAttrs = [];
            $scope.inputDataTable = [];
            $scope.detectionDataTable = [];
            $scope.repairDataTable = [];

            $scope.showChart=false;
            $scope.chartTitle = "";
            // 源数据和修复后的数据
            $scope.inputData= [];
            $scope.repairData = [];
            // 是否需要修复，flag
            $scope.detectionData = [];

            $scope.chartSeries = [];


            $scope.repairAlgorithmList = [
                {url: "inaccurate-MA", name:"Moving Average"},
                {url: "inaccurate-AR", name:"Auto Regression"},
                {url: "inaccurate-LR", name:"Linear Repair"},
            ];

            $scope.repairAlgorithm = "inaccurate-MA";
            $(repairAlgorithmAttrLabel).html("Window Size");
            $scope.repairAlgorithmAttr = 10;
            $scope.showRepairAlgorithmAttr=true;


            $scope.goToRepair = function()
            {
                $scope.detectionProcess = false;
                $scope.repairAlgorithm = "inaccurate-MA";
                $(repairAlgorithmAttrLabel).html("Window Size");
                $scope.repairAlgorithmAttr = 10;
                $scope.showRepairAlgorithmAttr=true;

                let key = 0, value = 0; // 不精确点和精确点
                for(let i = 0; i < $scope.detectionData.length; i++) {
                    if ($scope.detectionData[i])
                        key++;
                    else
                        value++;
                }

                communicationService.post('/api/fan-data-problem/statistics', {
                    operation: "update",
                    id: "1",
                    key: key,
                    value: value,
                }).then(function(){
                    console.log("inaccurate-sd-statistics: ("+key+","+value+")");
                }, function (err) {
                    console.warn("inaccurate-sd-statistics: " + err);
                });
            };

            $scope.$watch("repairAlgorithm", function(newValue, oldValue){
                if(newValue === oldValue)
                    return;
                $scope.repairData = [];
                if(newValue === "inaccurate-MA") {
                    $(repairAlgorithmAttrLabel).html("Window Size");
                    $scope.repairAlgorithmAttr = 10;
                    $scope.showRepairAlgorithmAttr=true;
                }
                if(newValue === "inaccurate-AR") {
                    $(repairAlgorithmAttrLabel).html("AR order");
                    $scope.repairAlgorithmAttr = 10;
                    $scope.showRepairAlgorithmAttr=true;
                }
                if(newValue === "inaccurate-LR")
                {
                    $(repairAlgorithmAttrLabel).html("");
                    $scope.showRepairAlgorithmAttr=false;
                }
            });

            // 选择属性后，视情况更新图
            $scope.$watch("usedAttr", function(newValue, oldValue){
                if(newValue === oldValue)
                    return;

                $scope.detectionData = [];
                $scope.repairData = [];

                newValue = newValue.toString();

                if("header" in $scope.inputDataTable && $.inArray(newValue, $scope.inputDataTable.header) !== -1)
                {
                    let data = [];
                    for (let i = 0; i < $scope.inputDataTable.header.length; i++)
                        if($scope.inputDataTable.header[i] === newValue)
                            for(let j = 0; j < $scope.inputDataTable.allData.length; j++)
                                data.push($scope.inputDataTable.allData[j][i]);

                    $scope.chartTitle = $scope.usedAttr;
                    $scope.inputData = data;
                    $scope.showChart = true;
                }
                else
                {
                    $scope.showChart = false;
                }
            });

            // 得到检测结果的table后，更新图
            $scope.$watch("detectionDataTable", function(newValue, oldValue){
                if(newValue === oldValue)
                    return;
                let data = [];
                for(let i = 0; i < $scope.detectionDataTable.allData.length; i++)
                {
                    data.push($scope.detectionDataTable.allData[i][1] === "1");
                    /*
                    if($scope.detectionDataTable.allData[i][1] === "1"
                        || (i > 0 && $scope.detectionDataTable.allData[i-1][1] === "1")
                        || (i + 1 < $scope.detectionDataTable.allData.length && $scope.detectionDataTable.allData[i+1][1] === "1"))
                        data.push($scope.detectionDataTable.allData[i][0]);
                    else
                        data.push(null);
                        */
                }
                $scope.detectionData = data;
            });

            // 得到修复结果的table后，更新图
            $scope.$watch("repairDataTable", function(newValue, oldValue) {
                if(newValue === oldValue)
                    return;
                let data = [];
                for(let i = 0; i < $scope.repairDataTable.allData.length; i++)
                {
                    data.push($scope.repairDataTable.allData[i][1]);
                    /*
                    if($scope.detectionDataTable.allData[i][1] === "1"
                        || (i > 0 && $scope.detectionDataTable.allData[i-1][1] === "1")
                        || (i + 1 < $scope.detectionDataTable.allData.length && $scope.detectionDataTable.allData[i+1][1] === "1"))
                        data.push($scope.repairDataTable.allData[i][1]);
                    else
                        data.push(null);

                    data.push([i, $scope.repairDataTable.allData[i][1]]);*/
                }
                $scope.repairData = data;
            });


            // 绘制echarts图，设置echarts的series
            $scope.$watch("{inputData:inputData, detectionData:detectionData, repairData:repairData}", function(newValue, oldValue){
                if(newValue === oldValue)
                    return;

                let inputData = $scope.inputData;
                let detectionData = $scope.detectionData;
                let repairData = $scope.repairData;
                let chartSeries = [];

                if(detectionData.length === 0)                  // 只选择了列，还未检测和修复
                {
                    let inputSeries = {
                        name: 'Normal Data',
                        type: 'line',
                        data: inputData,
                        symbol: 'circle',
                        symbolSize: 1,
                        lineStyle: {
                            normal: {
                                color: '#8a8c8e'
                            }
                        },
                        itemStyle: {
                            normal: {
                                color: '#8a8c8e'
                            }
                        }
                    };
                    chartSeries.push(inputSeries);
                }
                else if(repairData.length === 0)            // 检测了，但还未修复
                {
                    let inputSeries = {
                        name: 'Normal Data',
                        type: 'line',
                        data: inputData,
                        symbol: 'circle',
                        symbolSize: 1,
                        lineStyle: {
                            normal: {
                                color: '#8a8c8e'
                            }
                        },
                        itemStyle: {
                            normal: {
                                color: '#8a8c8e'
                            }
                        }
                    };
                    chartSeries.push(inputSeries);

                    let errData = [];
                    for(let i = 0; i < inputData.length; i++)
                        if(detectionData[i]
                            || (i > 0 && detectionData[i-1])
                            || (i < inputData.length - 1 && detectionData[i+1])
                        )
                            errData.push(inputData[i]);
                        else
                            errData.push(null);
                    let errSeries = {
                        name: 'Abnormal Data',
                        type: 'line',
                        data: errData,
                        symbol: 'circle',
                        symbolSize: 4,
                        tooltip:{
                            show: false
                        }
                        ,
                        lineStyle: {
                            normal: {
                                label:false,
                                color: '#ff0000'
                            }
                        }
                    };
                    chartSeries.push(errSeries);
                }
                else                                        // 进行了修复
                {
                    // 仅正常部分的源数据
                    let inputDataSegment = [];
                    // 异常点
                    let err = [];
                    // 仅异常部分的修复数据
                    let repairDataSegment = [];

                    for(let i = 0; i < inputData.length; i++)
                        if(detectionData[i]
                            || (i > 0 && detectionData[i-1])
                            || (i < inputData.length - 1 && detectionData[i+1]))
                            repairDataSegment.push(repairData[i]);
                        else
                            repairDataSegment.push(null);

                    for(let i = 0; i < inputData.length; i++)
                        if(detectionData[i]) {
                            inputDataSegment.push(null);
                            err.push({name : "inaccurate", coord:[i, inputData[i]]})
                        }
                        else
                            inputDataSegment.push(inputData[i]);

                    let inputSeries = {
                        name: 'Normal Data',
                        type: 'line',
                        data: inputDataSegment,
                        symbol: 'circle',
                        symbolSize: 1,
                        lineStyle: {
                            normal: {
                                color: '#8a8c8e'
                            }
                        },
                        itemStyle: {
                            normal: {
                                color: '#8a8c8e'
                            }
                        },
                        markPoint: {
                            name: 'Abnormal Data',
                            symbol: 'circle',
                            symbolSize: 5,
                            data: err,
                            label:{
                                show:false,
                            },
                            itemStyle: {
                                normal: {
                                    color: "#FF0000",
                                    label: {
                                        show: false
                                    }
                                }
                            }
                        }
                    };
                    chartSeries.push(inputSeries);

                    let repairDataSeries =
                        {
                            name: 'Repaired Data',
                            type: 'line',
                            data: repairDataSegment,
                            symbol: 'circle',
                            symbolSize: 1,
                            lineStyle: {
                                normal: {
                                    width: 3,
                                    color: '#1E90FF'
                                }
                            },
                            itemStyle: {
                                normal: {
                                    color: '#1E90FF'
                                }
                            }
                        };
                    chartSeries.push(repairDataSeries);
                }
                $scope.chartSeries = chartSeries;
            }, true);


            // 检测不精确的点
            $scope.detection = function() {
                $scope.repairData = [];
                communicationService.post('/api/fan-data-problem/inaccurate-SD', {
                    inputFilename: $scope.inputPath,
                    outputFilename: $scope.outputDetectionPath,
                    usedAttr: $scope.usedAttr,
                    detectionLeftBound: $scope.detectionLeftBound,
                    detectionRightBound: $scope.detectionRightBound,
                    detectionConfidence: $scope.detectionConfidence,
                    detectionSupport: $scope.detectionSupport
                }).then(function(data){
                    if (!(data instanceof Array)) {
                        data = [data];
                    }
                    let dataTables = [];
                    for (let table of data) {
                        dataTables.push({
                            header: table.header,
                            allData: table.dataList,
                            dataList: table.dataList.slice(0, 100),
                            more: table.dataList.length > 100
                        });
                    }
                    $scope.detectionDataTable = dataTables[0];
                    $(goToRepair).attr("disabled", false);
                }, function(err) {
                    console.warn(err);
                });
            };

            // 修复不精确的点
            $scope.repair = function() {
                communicationService.post('/api/fan-data-problem/'+$scope.repairAlgorithm, {
                    inputFilename: $scope.outputDetectionPath,
                    outputFilename: $scope.outputRepairPath,
                    algorithmAttr: $scope.repairAlgorithmAttr
                }).then(function(data){
                    if (!(data instanceof Array)) {
                        data = [data];
                    }
                    let dataTables = [];
                    for (let table of data) {
                        dataTables.push({
                            header: table.header,
                            allData: table.dataList,
                            dataList: table.dataList.slice(0, 100),
                            more: table.dataList.length > 100
                        });
                    }
                    $scope.repairDataTable = dataTables[0];
                }, function(err) {
                    console.warn(err);
                });
            };

            // 上传输入文件
            $scope.uploadFiles = function (file, errFiles) {
                $scope.detectionData = [];
                $scope.repairData = [];

                $scope.f = file;
                $scope.errFile = errFiles && errFiles[0];
                if (file) {
                    file.upload = Upload.upload({
                        url: '/api/chooseFile',
                        data: {file: file}
                    });

                    file.upload.then(function (response) {
                        $scope.inputPath = response.data.fileName;
                        $scope.preview();

                    }, function (error) {
                        console.log(error);
                    }, function (evt) {});
                }
            };

            // 展示属性的数据图
            $scope.preview = function() {
                $scope.showChart = false;
                communicationService.get('/api/data/csv', {
                    filename: $scope.inputPath
                }).then(function(data){
                    if (!data) {
                        return;
                    }
                    if (!(data instanceof Array)) {
                        data = [data];
                    }
                    let dataTables = [];
                    for (let table of data) {
                        dataTables.push({
                            header: table.header,
                            allData: table.dataList,
                            dataList: table.dataList.slice(0, 100),
                            more: table.dataList.length > 100
                        });
                    }
                    $scope.inputDataTable = dataTables[0];
                    $scope.autoCompleteAttrs = dataTables[0].header;

                }, function(err) {
                    console.warn(err);
                })
            }
        }]);
